"""
Compliance Item 核心业务逻辑
处理业务规则和数据转换，调用CRUD操作执行数据库交互
"""
from typing import Dict, Any, Optional, List
from uuid import UUID
from sqlalchemy.ext.asyncio import AsyncSession

from schemas.complianceItem import (
    ComplianceItemCreate,
    ComplianceItemUpdate,
    ComplianceItemResponse,
    ComplianceItemPagination
)
from crud import complianceItem as compliance_item_crud
from crud.relation import get_relations_by_risk
from log import log_info, log_error
from core.attachment import get_attachments

async def get_compliance_items(
    db: AsyncSession,
    skip: int = 0,
    limit: int = 100,
    filters: Optional[Dict[str, Any]] = None
) -> ComplianceItemPagination:
    """
    获取合规项列表，支持分页和过滤，并返回附件信息及关联关系

    Args:
        db: 数据库会话
        skip: 跳过记录数
        limit: 返回记录限制
        filters: 过滤条件字典

    Returns:
        包含总记录数和合规项列表的分页响应对象，含附件及关联关系
    """
    items, total = await compliance_item_crud.get_compliance_items(db, skip, limit, filters)

    # 异步获取每个合规项的附件信息和关联关系
    async def enrich_item(item):
        # 获取附件信息
        attachments = await get_attachments(db, item.id)
        
        # 获取关联关系
        related_guarantees = []
        
        if item.compliance_type == "risk":
            # 如果是风险项，获取关联的保障项
            relations = await get_relations_by_risk(db, item.id)
            related_guarantees = [str(relation.guarantee_item_id) for relation in relations]
        
        # 转换为字典
        if hasattr(item, 'model_dump'):
            item_dict = item.model_dump()
        else:
            # Convert ORM model to dict excluding private and SQLAlchemy attributes
            item_dict = {k: v for k, v in item.__dict__.items() if not k.startswith('_')}
        
        # 添加附件和关联关系
        item_dict.update({
            'attachments': attachments,
            'related_guarantees': related_guarantees
        })
        
        return ComplianceItemResponse.model_validate(item_dict)

    # 并行处理所有项目
    enriched_items = [await enrich_item(item) for item in items]

    return ComplianceItemPagination(
        total=total,
        items=enriched_items
    )


async def get_compliance_item(db: AsyncSession, item_id: UUID) -> Optional[ComplianceItemResponse]:
    """
    根据ID获取合规项

    Args:
        db: 数据库会话
        item_id: 合规项ID

    Returns:
        合规项响应对象，未找到则返回None
    """
    item = await compliance_item_crud.get_compliance_item_by_id(db, item_id)
    if item is None:
        return None
    
    return ComplianceItemResponse.model_validate(item)

async def create_compliance_item(db: AsyncSession, item_data: ComplianceItemCreate) -> ComplianceItemResponse:
    """
    创建新的合规项

    Args:
        db: 数据库会话
        item_data: 合规项创建数据

    Returns:
        创建的合规项响应对象
    """
    log_info(f"Creating new compliance item for assessment plan {item_data.assessment_plan_id}", 
            module="core.complianceItem")
    
    # 验证合规类型和风险级别的关系
    if item_data.compliance_type == "risk" and not item_data.risk_level:
        log_error("Failed to create compliance item: Risk type requires risk level", 
                 module="core.complianceItem")
        raise ValueError("当合规类型为风险时，必须指定风险级别")
    
    if item_data.compliance_type == "guarantee" and item_data.risk_level:
        # 确保保障类型的项目没有风险级别
        item_data_dict = item_data.model_dump()
        item_data_dict["risk_level"] = None
        item_data = ComplianceItemCreate(**item_data_dict)
    
    # 创建合规项记录
    item = await compliance_item_crud.create_compliance_item(db, item_data)
    
    return ComplianceItemResponse.model_validate(item)

async def bulk_create_compliance_items(
    db: AsyncSession, 
    items_data: List[ComplianceItemCreate]
) -> List[ComplianceItemResponse]:
    """
    批量创建合规项

    Args:
        db: 数据库会话
        items_data: 合规项创建数据列表

    Returns:
        创建的合规项响应对象列表
    """
    log_info(f"Bulk creating {len(items_data)} compliance items", module="core.complianceItem")
    
    # 验证所有项的合规类型和风险级别的关系
    for item_data in items_data:
        if item_data.compliance_type == "risk" and not item_data.risk_level:
            log_error("Failed to create compliance item: Risk type requires risk level", 
                     module="core.complianceItem")
            raise ValueError(f"项目 '{item_data.title}': 当合规类型为风险时，必须指定风险级别")
        
        if item_data.compliance_type == "guarantee" and item_data.risk_level:
            # 确保保障类型的项目没有风险级别
            item_data_dict = item_data.model_dump()
            item_data_dict["risk_level"] = None
            item_data = ComplianceItemCreate(**item_data_dict)
    
    # 批量创建合规项记录
    items = await compliance_item_crud.bulk_create_compliance_items(db, items_data)
    
    return [ComplianceItemResponse.model_validate(item) for item in items]

async def update_compliance_item(
    db: AsyncSession,
    item_id: UUID,
    item_data: ComplianceItemUpdate
) -> Optional[ComplianceItemResponse]:
    """
    更新合规项

    Args:
        db: 数据库会话
        item_id: 合规项ID
        item_data: 更新数据

    Returns:
        更新后的合规项响应对象，未找到则返回None
    """
    log_info(f"Updating compliance item with ID: {item_id}", module="core.complianceItem")
    
    # 获取现有合规项以进行验证
    existing_item = await compliance_item_crud.get_compliance_item_by_id(db, item_id)
    if existing_item is None:
        log_info(f"Update failed: No compliance item found with ID {item_id}", 
                module="core.complianceItem")
        return None
    
    # 特殊处理: 验证合规类型和风险级别的关系
    update_data_dict = item_data.model_dump(exclude_unset=True)
    new_compliance_type = update_data_dict.get("compliance_type", existing_item.compliance_type)
    new_risk_level = update_data_dict.get("risk_level", existing_item.risk_level)
    
    if new_compliance_type == "risk" and not new_risk_level:
        log_error(f"Update failed: Risk type requires risk level for item ID {item_id}", 
                 module="core.complianceItem")
        raise ValueError("当合规类型为风险时，必须指定风险级别")
    
    if new_compliance_type == "guarantee":
        # 确保保障类型的项目没有风险级别
        update_data_dict["risk_level"] = None
        item_data = ComplianceItemUpdate(**update_data_dict)
    
    # 更新合规项
    updated_item = await compliance_item_crud.update_compliance_item(db, item_id, item_data)
    if updated_item is None:
        return None

    
    # 异步获取每个合规项的附件信息和关联关系
    async def enrich_item(item):
        # 获取附件信息
        attachments = await get_attachments(db, item.id)
        
        # 获取关联关系
        related_guarantees = []
        
        if item.compliance_type == "risk":
            # 如果是风险项，获取关联的保障项
            relations = await get_relations_by_risk(db, item.id)
            related_guarantees = [str(relation.guarantee_item_id) for relation in relations]
        
        # 转换为字典
        if hasattr(item, 'model_dump'):
            item_dict = item.model_dump()
        else:
            # Convert ORM model to dict excluding private and SQLAlchemy attributes
            item_dict = {k: v for k, v in item.__dict__.items() if not k.startswith('_')}
        
        # 添加附件和关联关系
        item_dict.update({
            'attachments': attachments,
            'related_guarantees': related_guarantees
        })
        
        return ComplianceItemResponse.model_validate(item_dict)

    # 并行处理所有项目
    enriched_items = await enrich_item(updated_item) 
    
    return enriched_items

async def delete_compliance_item(db: AsyncSession, item_id: UUID) -> bool:
    """
    删除合规项

    Args:
        db: 数据库会话
        item_id: 合规项ID

    Returns:
        删除成功返回True，未找到则返回False
    """
    log_info(f"Deleting compliance item with ID: {item_id}", module="core.complianceItem")
    
    # 删除合规项
    return await compliance_item_crud.delete_compliance_item(db, item_id)
